#include "ManejadorElementos.h"

ManejadorElementos::ManejadorElementos() {

	elementos = new set<Elemento*>;

	elementosModificados = new list<Elemento*>;

}

ManejadorElementos::~ManejadorElementos() {

	if (elementos != NULL) {

		elementos->clear();
		delete elementos;
		elementos = NULL;
	}

	if ( elementosModificados != NULL) {

		elementosModificados->clear();
		delete elementosModificados;
		elementosModificados = NULL;
	}
}

/*
*	Agrega un elemento al conjunto.
*
*	/R Devuelve NULL si no pudo agregar el elemento, o el mismo elemento caso contrario.
*/
Elemento* ManejadorElementos::agregar(Elemento* elemento) {

	Elemento* resultado = NULL;

	if (elementos->insert(elemento).second == true) {

		elementosModificados->push_back(elemento);

		resultado = elemento;
	}
	
	return resultado;
}

/*
*	Actualiza(Reemplaza) un elemento del conjunto por otro.
*
*	/R Devuelve NULL si no pudo reemplazar el elemento, o el mismo elemento caso contrario.
*/
Elemento* ManejadorElementos::actualizar(Elemento* elemento) {

	Elemento* resultado = false;

	set<Elemento*>::iterator iterador = elementos->find(elemento);
	set<Elemento*>::iterator iterador2 = iterador;

	if (iterador != elementos->end()) {
		
		iterador2 = iterador;
		elementosModificados->push_back(elemento);

		elementos->insert(iterador, elemento);
		elementos->erase(iterador);
	}

	return resultado;
}

/*
*	Quita un elemento del conjunto si pertenece.
*
*	/R Devuelve NULL si no pudo quitar el elemento, o el mismo elemento caso contrario.
*/
Elemento* ManejadorElementos::quitar(Elemento* elemento) {

	if (elementos->erase(elemento) != 1) {

		elementosModificados->push_back(elemento);

		elemento = NULL;

	}

	return elemento;
}

list<Elemento*>* ManejadorElementos::operacion(funcionPorParametro funcion, list<Elemento*>* listaElementos) {

	list<Elemento*>::iterator iterador = listaElementos->begin();

	while ( iterador != listaElementos->end() ) {

		if ( (this->*funcion)(*iterador) != NULL )

			iterador = listaElementos->erase(iterador);
	}

	return listaElementos;
}

list<Elemento*>* ManejadorElementos::agregar(list<Elemento*>* listaElementos) {

	return operacion( &ManejadorElementos::agregar, listaElementos);
}

list<Elemento*>* ManejadorElementos::actualizar(list<Elemento*>* listaElementos) {

	return operacion( &ManejadorElementos::actualizar, listaElementos);
}

list<Elemento*>* ManejadorElementos::quitar(list<Elemento*>* listaElementos) {

	return operacion( &ManejadorElementos::quitar, listaElementos);
}

void ManejadorElementos::quitarElementos() {

	elementos->clear();
}

bool ManejadorElementos::tieneElementos() {

	return !elementos->empty();
}

bool ManejadorElementos::huboElementosModificados() {

	return !elementosModificados->empty();
}

Elemento* ManejadorElementos::operator<< (Elemento* elemento) {

	return agregar(elemento);
}

Elemento* ManejadorElementos::operator|| (Elemento* elemento) {

	return actualizar(elemento);
}


Elemento* ManejadorElementos::operator>> (Elemento* elemento) {

	return quitar(elemento);
}

list<Elemento*>* ManejadorElementos::getElementosModificados() {
	
	list<Elemento*>* lista = NULL;
	
	if (!elementosModificados->empty()) {

		lista = elementosModificados;

		elementosModificados = new list<Elemento*>;

	}

	return lista;
}